package com.example.springboot.config.filter;


import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.springboot.common.Result;
import com.example.springboot.entity.User;
import com.example.springboot.entity.UserContext;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.service.IUserService;
import com.example.springboot.common.Constants;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson2.JSON;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Objects;
;

@Component
@RequiredArgsConstructor
public class JwtFilter implements Filter {


    private final IUserService userService;


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;


        // 获取请求的 URI
        String path = httpRequest.getRequestURI();

        // 检查是否是需要放行的路径
        if (shouldAllowAccess(path)) {
            chain.doFilter(request, response); // 放行
            return;
        }
        String token = httpRequest.getHeader("token");
        if (StrUtil.isBlank(token)) {
            token = httpRequest.getParameter("token");
        }

        if (StrUtil.isBlank(token)) {
            returnJson(httpResponse,JSON.toJSONString(Result.error(Constants.CODE_401, "请重新登录")));
            return;
        }

        String userId = null;
        try {
            userId = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException j) {
            returnJson(httpResponse,JSON.toJSONString(Result.error(Constants.CODE_401, "请重新登录")));
            return;
//            throw new ServiceException(Constants.CODE_401, "token验证失败，请重新登录");
        }

        User user = userService.getById(userId);
        if (user == null) {
            returnJson(httpResponse,JSON.toJSONString(Result.error(Constants.CODE_401, "请重新登录")));
            return;
//            throw new ServiceException(Constants.CODE_401, "用户不存在，请重新登录");
        }
        if(Objects.equals(user.getIsDisabled(), "1")){
            returnJson(httpResponse,JSON.toJSONString(Result.error(Constants.CODE_700, "当前访问权限不够，请联系管理员")));
            return;
        }

        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
        try {
            jwtVerifier.verify(token); // 验证token
        } catch (JWTVerificationException e) {
//            throw new ServiceException(Constants.CODE_401, "token验证失败，请重新登录");
            returnJson(httpResponse,JSON.toJSONString(Result.error(Constants.CODE_401, "请重新登录")));
            return;
        }
        UserContext.setUser(user);
        chain.doFilter(request, response); // 继续链中的下一个过滤器
    }

    private void returnJson(HttpServletResponse response, String json){
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(json);

        } catch (IOException e) {
        } finally {
            if (writer != null)
                writer.close();
        }
    }

    private boolean shouldAllowAccess(String path) {
        return path.equals("/metAlarm/getMetAlarmInfoByUser")
                || path.equals("/user/adminLogin")
                || path.equals("/user/wxLogin")
                || path.equals("/user/loginAndBind")
                || path.equals("/user/login")
                || path.equals("/user/hello")
                || path.equals("/user/register")
                || path.matches(".*/export")
                || path.matches(".*/import")
                || path.matches("/file/.*");
    }
    @Override
    public void destroy() {
        // Filter 销毁操作
        UserContext.removeUser();
    }
}
